#include<iostream>
#include<cstring>
using namespace std;
const int N = 1010;
int f[N];
int v[N], w[N];
int n, m;
int main()
{
    cin >> n >> m;
//     for(int i=1;i<=n;i++)
//     {
//         cin>>v[i]>>w[i];
//     }
//     for (int i = 1;i <= n;i++)
//     {
//         for (int j = 0;j <= m;j++)
//         {
//             //不选
//             f[i][j] = f[i - 1][j];
//             if (j >= v[i]) f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
//         }
//     }
//     cout << f[n][m] << endl;
//     memset(f, -0x3f, sizeof(f));
//     f[0][0] = 0;
//     for (int i = 1;i <= n;i++)
//     {
//         for (int j = 0;j <= m;j++)
//         {
//             f[i][j] = f[i - 1][j];
//             if (j >= v[i]) f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
//         }
//     }
//     if (f[n][m] > 0) cout << f[n][m] << endl;
//     else cout << 0 << endl;

    //空间优化
     for(int i=1;i<=n;i++)
    {
        cin>>v[i]>>w[i];
    }
    for (int i = 1;i <= n;i++)
    {
        //注意这里一定要从左往右因为我们实际拿的是本行的值，并且要保证拿的值已经更新过了
        for (int j = v[i];j <= m;j++)
        {
             f[j] = max(f[j], f[j - v[i]] + w[i]);
        }
    }
    cout << f[m] << endl;
    memset(f, -0x3f, sizeof(f));
    f[0] = 0;
    for (int i = 1;i <= n;i++)
    {
        for (int j = v[i];j <= m;j++)
        {
            f[j] = max(f[j], f[j - v[i]] + w[i]);
        }
    }
    if (f[m] > 0) cout << f[m] << endl;
    else cout << 0 << endl;
    return 0;
}